﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Data.Linq;
using DataObject.Database;
using DataObject.Core;
using DataObject.Model;

namespace DataObject.DataAccess
{
    public class LocationDAO : DataBaseProcessBase<Location, OBSDataContext>
    {
        #region Singleton
        public static LocationDAO CreateInstant()
        {
            return new LocationDAO();
        }
        #endregion

        public IList<Location> GetAllLocations()
        {
            using (OBSDataContext biocode = new OBSDataContext(base.connectionString))
            {
                return biocode.Locations.OrderBy(x => x.LocationName).ToList();
            }
        }

        public IList<Location> GetLocations(int? Page, int? Row, out int Count, HashSet<string> SortClause)
        {
            using (OBSDataContext db = new OBSDataContext(base.connectionString))
            {
                db.DeferredLoadingEnabled = false; //disabling will turn off deferred loading (lazy fetch)

                var query = (from x in db.Locations select x);
                for (int i = SortClause.Count - 1; i >= 0; i--)
                    query = query.OrderBy(SortClause.ElementAt(i));
                Count = query.Count();
                if (Page.HasValue && Row.HasValue)
                    return query.PageIQuery(Page.Value, Row.Value).ToList();
                return query.ToList();
            }
        }

        public Location GetLocation(int locationID)
        {
            using (OBSDataContext biocode = new OBSDataContext(base.connectionString))
            {
                return biocode.Locations.SingleOrDefault(x => x.LocationID == locationID);
            }
        }

        public bool InsertLocation(Location location)
        {
            bool result = false;

            using (OBSDataContext biocode = new OBSDataContext(base.connectionString))
            {
                biocode.Locations.InsertOnSubmit(location);

                try
                {
                    biocode.SubmitChanges();
                    result = true;
                }
                catch (ChangeConflictException)
                {
                    //  A possible concurrency exception occurred.  Let's see if
                    //  we can resolve it.
                    foreach (var conflict in biocode.ChangeConflicts)
                    {
                        conflict.Resolve(RefreshMode.KeepCurrentValues);
                    }
                    try
                    {
                        biocode.SubmitChanges();
                        result = true;
                    }
                    catch (ChangeConflictException)
                    {
                        //  It didn't work, so throw a new exception.
                        // throw new Exception("A concurrency error occurred!");
                    }
                    catch (Exception)
                    {
                        // throw new Exception("There was an error saving this record!");
                    }
                }
                catch
                {

                }
            }

            return result;
        }

        public bool UpdateLocation(Location model)
        {
            bool result = false;

            using (OBSDataContext biocode = new OBSDataContext(base.connectionString))
            {
                var entity = biocode.Locations.SingleOrDefault(x => x.LocationID == model.LocationID);
                if (null != entity)
                {
                    entity.LocationName = model.LocationName;

                    try
                    {
                        biocode.SubmitChanges();
                        result = true;
                    }
                    catch (ChangeConflictException)
                    {
                        //  A possible concurrency exception occurred.  Let's see if
                        //  we can resolve it.
                        foreach (var conflict in biocode.ChangeConflicts)
                        {
                            conflict.Resolve(RefreshMode.KeepCurrentValues);
                        }
                        try
                        {
                            biocode.SubmitChanges();
                            result = true;
                        }
                        catch (ChangeConflictException)
                        {
                            //  It didn't work, so throw a new exception.
                            // throw new Exception("A concurrency error occurred!");
                        }
                        catch (Exception)
                        {
                            // throw new Exception("There was an error saving this record!");
                        }
                    }
                    catch
                    {
                        // twice
                        try
                        {
                            biocode.SubmitChanges();
                            result = true;
                        }
                        catch (Exception)
                        {
                            // throw new Exception("There was an error saving this record!");
                        }
                    }
                }
            }

            return result;
        }

        public bool DeleteLocation(int locationID)
        {
            bool result = false;

            using (OBSDataContext biocode = new OBSDataContext(base.connectionString))
            {
                Location location = biocode.Locations.SingleOrDefault(x => x.LocationID == locationID);
                if (null != location)
                {
                    biocode.Locations.DeleteOnSubmit(location);

                    try
                    {
                        biocode.SubmitChanges();
                        result = true;
                    }
                    catch (ChangeConflictException)
                    {
                        //  A possible concurrency exception occurred.  Let's see if
                        //  we can resolve it.
                        foreach (var conflict in biocode.ChangeConflicts)
                        {
                            conflict.Resolve(RefreshMode.KeepCurrentValues);
                        }
                        try
                        {
                            biocode.SubmitChanges();
                            result = true;
                        }
                        catch (ChangeConflictException)
                        {
                            //  It didn't work, so throw a new exception.
                            // throw new Exception("A concurrency error occurred!");
                        }
                        catch (Exception)
                        {
                            // throw new Exception("There was an error saving this record!");
                        }
                    }
                    catch
                    {
                        // twice
                        try
                        {
                            biocode.SubmitChanges();
                            result = true;
                        }
                        catch (Exception)
                        {
                            // throw new Exception("There was an error saving this record!");
                        }
                    }
                }
            }

            return result;
        }

    }
}
